package marlon.smsbatcheditor.activity;

import java.util.BitSet;

import marlon.smsbatcheditor.Constants;
import marlon.smsbatcheditor.R;
import marlon.smsbatcheditor.db.RuleDAO;
import marlon.smsbatcheditor.db.SmsDAO;
import marlon.smsbatcheditor.model.Rule;
import marlon.smsbatcheditor.model.Sms;
import marlon.smsbatcheditor.utils.DateUtils;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.CompoundButton.OnCheckedChangeListener;

/**
 * 
 * @author marlonyao<yaolei135@gmail.com>
 */
public class PreviewActivity extends ListActivity implements OnClickListener {
	private TextView tvTotal;
	private ListView lvSms;
	private SmsCursorAdapter smsAdapter;
	private Rule rule;
	private RuleDAO ruleDAO;
	private Cursor cursor;
	private SmsDAO smsDAO;
	
	private Button btnApply;
	private Button btnCancel;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.preview);
        
        ruleDAO = new RuleDAO(this);
        long ruleId = getIntent().getLongExtra("rule_id", -1L);
        rule = ruleDAO.findById(ruleId);
        setTitle("Preview Rule \"" + rule.getName() + "\"");
        
        tvTotal = (TextView) findViewById(R.id.tvTotal);
        tvTotal = new TextView(this);
        lvSms = getListView();
        btnApply = (Button) findViewById(R.id.btnApply);
        btnCancel = (Button) findViewById(R.id.btnCancel);
        btnApply.setOnClickListener(this);
        btnCancel.setOnClickListener(this);
        
        smsDAO = new SmsDAO(this);
        
        cursor = smsDAO.find(rule);
        startManagingCursor(cursor);
        smsAdapter = new SmsCursorAdapter(this, cursor);
        lvSms.addHeaderView(tvTotal);
        lvSms.setAdapter(smsAdapter);
        
        updateView();
    }

	@Override
	public void onClick(View v) {
		if (v == btnApply) {
       		AlertDialog.Builder builer = new AlertDialog.Builder(this);
       		builer.setMessage("Are you sure to apply this rule to selected SMS(es)?")
       			.setCancelable(false)
       			.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						int count = applyRule();
						Intent intent = new Intent();
						intent.putExtra("update_count", count);
						setResult(RESULT_OK, intent);
						finish();
					}
				}).setNegativeButton("No", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.cancel();
					}
				});
       		builer.create().show();
		} else if (v == btnCancel) {
			setResult(RESULT_CANCELED);
			finish();
		}
	}

	private int applyRule() {
		int count = 0;
		for (int i = 0; i < smsAdapter.getCount(); i++) {
			if (!smsAdapter.isItemChecked(i)) continue;
			
			Cursor cursor = (Cursor) smsAdapter.getItem(i);
			Sms sms = new Sms(cursor);
			
			if (smsDAO.update(sms, rule))
				++count;
		}
		
		if (count > 0)
			Toast.makeText(this, "Updated " + count + " SMS(es)", Toast.LENGTH_SHORT).show();
		return count;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(0, Constants.MENU_SELECT_ALL, Menu.NONE, "Select All");
		menu.add(0, Constants.MENU_SELECT_NONE, Menu.NONE, "Select None");
		menu.add(1, Constants.MENU_EDIT_RULE, Menu.NONE, "Edit Rule");
		
		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		boolean visible = smsAdapter.getCount() > 0;
		menu.getItem(0).setVisible(visible);
		menu.getItem(1).setVisible(visible);
		
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case Constants.MENU_SELECT_ALL:
			smsAdapter.selectAll();
			return true;
		case Constants.MENU_SELECT_NONE:
			smsAdapter.selectNone();
			return true;
		case Constants.MENU_EDIT_RULE:
			Intent intent = new Intent(this, EditRuleActivity.class);
       		intent.setAction(Intent.ACTION_EDIT);
       		intent.putExtra("rule_id", rule.getId());
       		startActivityForResult(intent, 0);
		default:
			return super.onOptionsItemSelected(item);
		}
	}
	
    @Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	super.onActivityResult(requestCode, resultCode, data);
    	if (resultCode == RESULT_OK) {
    		// reload rule
    		rule = ruleDAO.findById(rule.getId());
    		if (cursor != null) {
    			stopManagingCursor(cursor);
    			cursor.close();
    		}
    		cursor = smsDAO.find(rule);
    		startManagingCursor(cursor);
    		smsAdapter = new SmsCursorAdapter(this, cursor);
            lvSms.setAdapter(smsAdapter);
            
            updateView();
    	}
	}
    
    private void updateView() {
        if (smsAdapter.getCount() > 0) {
        	tvTotal.setText("Found " + smsAdapter.getCount() + " SMS(es).");
        }
    }
    
    private class SmsCursorAdapter extends CursorAdapter {
    	private LayoutInflater inflater = null;
    	private BitSet smsSet;
    	
		public SmsCursorAdapter(Context context, Cursor c) {
			super(context, c);
			
			inflater = LayoutInflater.from(context);
			smsSet = new BitSet(c.getCount());
			smsSet.set(0, smsSet.size());
			
			fireSMSChanged();
		}

		@Override
		public void bindView(View view, final Context context, final Cursor cursor) {
			String address = cursor.getString(cursor.getColumnIndexOrThrow("address"));
			String body = cursor.getString(cursor.getColumnIndexOrThrow("body"));
			long date = cursor.getLong(cursor.getColumnIndexOrThrow("date"));
			
			TextView tvAddress = (TextView) view.findViewById(R.id.tvAddress);
			TextView tvBody = (TextView) view.findViewById(R.id.tvBody);
			TextView tvDate = (TextView) view.findViewById(R.id.tvTime);
			final CheckBox cbSms = (CheckBox) view.findViewById(R.id.cbSms);
			tvAddress.setText(address);
			tvBody.setText(body);
			tvDate.setText(DateUtils.getShortDateTimeString(date));
			final int pos = cursor.getPosition();
			cbSms.setChecked(smsSet.get(pos));
			cbSms.setOnCheckedChangeListener(new OnCheckedChangeListener() {
				@Override
				public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
					smsSet.set(pos, isChecked);
					fireSMSChanged();
				}
			});
		}

		@Override
		public View newView(final Context context, final Cursor cursor, ViewGroup parent) {
			View v = inflater.inflate(R.layout.sms_item, parent, false);
			
			final long smsId = cursor.getLong(cursor.getColumnIndexOrThrow("_id"));
			v.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					Intent intent = new Intent(context, SMSDetailActivity.class);
					intent.putExtra("sms_id", smsId);
					context.startActivity(intent);
				}
			});
			return v;
		}
    	
		public boolean isItemChecked(int pos) {
			return smsSet.get(pos);
		}
		
		public void selectAll() {
			smsSet.set(0, smsSet.size());
			this.notifyDataSetChanged();
		}
		
		public void selectNone() {
			smsSet.clear();
			this.notifyDataSetChanged();
		}
		
		private void fireSMSChanged() {
			btnApply.setEnabled(smsSet.cardinality() > 0);
		}
    }
}
